1 package edu.jiangxin.apktoolbox.main;
2
3 import edu.jiangxin.apktoolbox.Version;
4 import edu.jiangxin.apktoolbox.android.dumpsys.DumpsysPanel;
5 import edu.jiangxin.apktoolbox.convert.base.BaseConvertPanel;
6 import edu.jiangxin.apktoolbox.convert.color.ColorConvertPanel;
7 import edu.jiangxin.apktoolbox.convert.color.ColorPickerPanel;
8 import edu.jiangxin.apktoolbox.convert.encoding.GarbledTextRecoveryPanel;
9 import edu.jiangxin.apktoolbox.convert.protobuf.supervised.SupervisedProtobufConvertPanel;
10 import edu.jiangxin.apktoolbox.convert.protobuf.unsupervised.UnsupervisedProtobufConvertPanel;
11 import edu.jiangxin.apktoolbox.convert.relationship.RelationShipConvertPanel;
12 import edu.jiangxin.apktoolbox.convert.time.TimeConvertPanel;
13 import edu.jiangxin.apktoolbox.convert.zh2unicode.Zh2UnicodeConvertPanel;
14 import edu.jiangxin.apktoolbox.file.batchrename.BatchRenamePanel;
15 import edu.jiangxin.apktoolbox.file.EncodeConvertPanel;
16 import edu.jiangxin.apktoolbox.file.OsConvertPanel;
17 import edu.jiangxin.apktoolbox.file.checksum.ChecksumPanel;
18 import edu.jiangxin.apktoolbox.file.password.recovery.RecoveryPanel;
19 import edu.jiangxin.apktoolbox.file.duplicate.DuplicateSearchPanel;
20 import edu.jiangxin.apktoolbox.file.zhconvert.ZhConvertPanel;
21 import edu.jiangxin.apktoolbox.help.*;
22 import edu.jiangxin.apktoolbox.android.i18n.I18nAddPanel;
23 import edu.jiangxin.apktoolbox.android.i18n.I18nFindLongestPanel;
24 import edu.jiangxin.apktoolbox.android.i18n.I18nRemovePanel;
25 import edu.jiangxin.apktoolbox.android.monkey.MonkeyPanel;
26 import edu.jiangxin.apktoolbox.help.settings.SettingsPanel;
27 import edu.jiangxin.apktoolbox.pdf.finder.PdfFinderPanel;
28 import edu.jiangxin.apktoolbox.pdf.passwordremover.PdfPasswordRemoverPanel;
29 import edu.jiangxin.apktoolbox.pdf.stat.PdfStatPanel;
30 import edu.jiangxin.apktoolbox.reverse.*;
31 import edu.jiangxin.apktoolbox.android.screenshot.ScreenShotPanel;
32 import edu.jiangxin.apktoolbox.reverse.ApktoolPanel;
33 import edu.jiangxin.apktoolbox.swing.extend.EasyFrame;
34 import edu.jiangxin.apktoolbox.swing.extend.EasyPanel;
35 import edu.jiangxin.apktoolbox.swing.extend.listener.ChangeMenuListener;
36 import edu.jiangxin.apktoolbox.swing.extend.listener.ChangeMenuToUrlListener;
37 import edu.jiangxin.apktoolbox.swing.extend.listener.IPreChangeMenuCallBack;
38 import edu.jiangxin.apktoolbox.swing.extend.plugin.ChangeMenuPreparePluginController;
39 import edu.jiangxin.apktoolbox.swing.extend.plugin.PluginPanel;
40 import edu.jiangxin.apktoolbox.swing.keeper.UiStateKeeper;
41 import edu.jiangxin.apktoolbox.utils.Utils;
42 import org.apache.commons.configuration2.Configuration;
43 import org.apache.commons.lang3.StringUtils;
44 import org.apache.logging.log4j.LogManager;
45 import org.apache.logging.log4j.Logger;
46
47 import javax.swing.*;
48 import javax.swing.border.EmptyBorder;
49 import java.awt.*;
50 import java.awt.event.*;
51 import java.io.Serial;
52 import java.lang.reflect.InvocationTargetException;
53 import java.text.MessageFormat;
54 import java.util.Locale;
55 import java.util.Objects;
56
57
58
59
60
61 public final class MainFrame extends EasyFrame {
62
63 @Serial
64 private static final long serialVersionUID = 1L;
65
66 private JPanel contentPane;
67 private EasyPanel currentEasyPanel = null;
68 private JMenuBar menuBar;
69
70 public static void main(String[] args) {
71 final Logger logger = LogManager.getLogger(MainFrame.class.getSimpleName());
72 boolean isEnvironmentOk = Utils.checkAndInitEnvironment();
73 if (!isEnvironmentOk) {
74 logger.error("Environment is not ready, exit");
75 return;
76 }
77 EventQueue.invokeLater(() -> {
78 Configuration conf = Utils.getConfiguration();
79 String lookAndFeelClassName = conf.getString("look.and.feel.class.name");
80 if (StringUtils.isEmpty(lookAndFeelClassName)) {
81 lookAndFeelClassName = "com.formdev.flatlaf.FlatDarculaLaf";
82 conf.setProperty("look.and.feel.class.name", lookAndFeelClassName);
83 }
84 try {
85 UIManager.setLookAndFeel(lookAndFeelClassName);
86 } catch (UnsupportedLookAndFeelException | ClassNotFoundException | InstantiationException | IllegalAccessException e) {
87 logger.error("setLookAndFeel failed, use default instead", e);
88 }
89
90 String currentLocaleLanguage = conf.getString("locale.language");
91 if (StringUtils.isEmpty(currentLocaleLanguage)) {
92 currentLocaleLanguage = Locale.ENGLISH.getLanguage();
93 conf.setProperty("locale.language", currentLocaleLanguage);
94 }
95 Locale.setDefault(Locale.forLanguageTag(currentLocaleLanguage));
96
97 MainFrame frame = new MainFrame();
98
99 boolean isAlwaysOnTop = conf.getBoolean("always.on.top", false);
100 conf.setProperty("always.on.top", isAlwaysOnTop);
101 frame.setAlwaysOnTop(isAlwaysOnTop);
102
103 frame.setVisible(true);
104 });
105 }
106
107 public MainFrame() {
108 super();
109 initialize();
110 if (SystemTray.isSupported()) {
111 configSystemTray();
112 }
113
114 setTitle(MessageFormat.format(bundle.getString("main.title"), Version.VERSION));
115 setDefaultCloseOperation(EXIT_ON_CLOSE);
116 setMenuBar();
117 contentPane = new JPanel();
118 contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
119 contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
120 contentPane.add(Box.createVerticalGlue());
121 EasyPanel initPanel = new AboutPanel();
122 initPanel.init();
123 initPanel.setBorder(BorderFactory.createTitledBorder(bundle.getString("help.about.title")));
124 contentPane.add(initPanel);
125 contentPane.add(Box.createVerticalGlue());
126 setContentPane(contentPane);
127 refreshSizeAndLocation();
128 }
129
130 private void configSystemTray() {
131 SystemTray systemTray = SystemTray.getSystemTray();
132 PopupMenu popupMenu = new PopupMenu();
133 final MenuItem show = new MenuItem("Open");
134 final MenuItem exit = new MenuItem("Close");
135 ActionListener actionListener = e -> {
136 if (e.getSource() == show) {
137 setExtendedState(NORMAL);
138 setVisible(true);
139 }
140 if (e.getSource() == exit) {
141 dispatchEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING));
142 }
143 };
144 exit.addActionListener(actionListener);
145 show.addActionListener(actionListener);
146 popupMenu.add(show);
147 popupMenu.add(exit);
148 TrayIcon trayIcon = new TrayIcon(image, "系统托盘", popupMenu);
149 trayIcon.setImageAutoSize(true);
150 try {
151 systemTray.add(trayIcon);
152 } catch (AWTException e) {
153 logger.error("add icon to tray failed");
154 }
155 trayIcon.addMouseListener(new MouseAdapter() {
156 @Override
157 public void mouseClicked(MouseEvent e) {
158 if (e.getClickCount() == 2) {
159 setExtendedState(NORMAL);
160 setVisible(true);
161 }
162 }
163 });
164 }
165
166 private void setMenuBar() {
167 menuBar = new JMenuBar();
168 setJMenuBar(menuBar);
169
170 createReverseMenu();
171
172 createAndroidMenu();
173
174 createPdfMenu();
175
176 createFileMenu();
177
178 createConvertMenu();
179
180 createHelpMenu();
181 }
182
183 private void createHelpMenu() {
184 JMenu helpMenu = new JMenu(bundle.getString("help.title"));
185 menuBar.add(helpMenu);
186
187 JMenuItem documentMenuItem = new JMenuItem(bundle.getString("help.document.title"));
188 documentMenuItem.addActionListener(new ChangeMenuToUrlListener(Constant.URL_DOCUMENT));
189 helpMenu.add(documentMenuItem);
190
191 JMenuItem settingsMenuItem = new JMenuItem(bundle.getString("help.settings.title"));
192 settingsMenuItem.addActionListener(new ChangeMenuToPanelListener(SettingsPanel.class, settingsMenuItem.getText()));
193 helpMenu.add(settingsMenuItem);
194
195 JMenuItem feedbackMenuItem = new JMenuItem(bundle.getString("help.feedback.title"));
196 feedbackMenuItem.addActionListener(new ChangeMenuToUrlListener(Constant.URL_FEEDBACK));
197 helpMenu.add(feedbackMenuItem);
198
199 JMenuItem checkUpdateMenuItem = new JMenuItem(bundle.getString("help.checkupdate.title"));
200 checkUpdateMenuItem.addActionListener(new CheckUpdateActionListener(this));
201 helpMenu.add(checkUpdateMenuItem);
202
203 JMenuItem contributeMenuItem = new JMenuItem(bundle.getString("help.contribute.title"));
204 contributeMenuItem.addActionListener(new ChangeMenuToUrlListener(Constant.URL_CONTRIBUTE));
205 helpMenu.add(contributeMenuItem);
206
207 JMenuItem aboutMenuItem = new JMenuItem(bundle.getString("help.about.title"));
208 aboutMenuItem.addActionListener(new ChangeMenuToPanelListener(AboutPanel.class, aboutMenuItem.getText()));
209 helpMenu.add(aboutMenuItem);
210 }
211
212 private void createPdfMenu() {
213 JMenu pdfMenu = new JMenu(bundle.getString("pdf.title"));
214 menuBar.add(pdfMenu);
215
216 JMenuItem pdfStatMenuItem = new JMenuItem(bundle.getString("pdf.stat.title"));
217 pdfStatMenuItem.addActionListener(new ChangeMenuToPanelListener(PdfStatPanel.class, pdfStatMenuItem.getText()));
218 pdfMenu.add(pdfStatMenuItem);
219
220 JMenuItem pdfFinderMenuItem = new JMenuItem(bundle.getString("pdf.finder.title"));
221 pdfFinderMenuItem.addActionListener(new ChangeMenuToPanelListener(PdfFinderPanel.class, pdfFinderMenuItem.getText()));
222 pdfMenu.add(pdfFinderMenuItem);
223
224 JMenuItem pdfPasswordRemoverMenuItem = new JMenuItem(bundle.getString("pdf.password.remover.title"));
225 pdfPasswordRemoverMenuItem.addActionListener(new ChangeMenuToPanelListener(PdfPasswordRemoverPanel.class, pdfPasswordRemoverMenuItem.getText()));
226 pdfMenu.add(pdfPasswordRemoverMenuItem);
227 }
228
229 private void createFileMenu() {
230 JMenu fileMenu = new JMenu(bundle.getString("file.title"));
231 menuBar.add(fileMenu);
232
233 JMenuItem osConvertMenuItem = new JMenuItem(bundle.getString("file.os.convert.title"));
234 osConvertMenuItem.addActionListener(new ChangeMenuToPanelListener(OsConvertPanel.class, osConvertMenuItem.getText()));
235 fileMenu.add(osConvertMenuItem);
236
237 JMenuItem encodeConvertMenuItem = new JMenuItem(bundle.getString("file.encode.convert.title"));
238 encodeConvertMenuItem.addActionListener(new ChangeMenuToPanelListener(EncodeConvertPanel.class, encodeConvertMenuItem.getText()));
239 fileMenu.add(encodeConvertMenuItem);
240
241 JMenuItem zhConvertMenuItem = new JMenuItem(bundle.getString("file.zh.convert.title"));
242 zhConvertMenuItem.addActionListener(new ChangeMenuToPanelListener(ZhConvertPanel.class, zhConvertMenuItem.getText()));
243 fileMenu.add(zhConvertMenuItem);
244
245 JMenuItem duplicateFindMenuItem = new JMenuItem(bundle.getString("file.duplicate.title"));
246 duplicateFindMenuItem.addActionListener(new ChangeMenuToPanelListener(DuplicateSearchPanel.class, duplicateFindMenuItem.getText()));
247 fileMenu.add(duplicateFindMenuItem);
248
249 JMenuItem batchRenameMenuItem = new JMenuItem(bundle.getString("file.batch.rename.title"));
250 batchRenameMenuItem.addActionListener(new ChangeMenuToPanelListener(BatchRenamePanel.class, batchRenameMenuItem.getText()));
251 fileMenu.add(batchRenameMenuItem);
252
253 JMenuItem checkSumMenuItem = new JMenuItem(bundle.getString("file.check.summary.title"));
254 checkSumMenuItem.addActionListener(new ChangeMenuToPanelListener(ChecksumPanel.class, checkSumMenuItem.getText()));
255 fileMenu.add(checkSumMenuItem);
256
257 JMenuItem recoveryMenuItem = new JMenuItem(bundle.getString("file.password.recovery.title"));
258 recoveryMenuItem.addActionListener(new ChangeMenuToPanelListener(RecoveryPanel.class, recoveryMenuItem.getText()));
259 fileMenu.add(recoveryMenuItem);
260 }
261
262 private void createConvertMenu() {
263 JMenu convertMenu = new JMenu(bundle.getString("convert.title"));
264 menuBar.add(convertMenu);
265
266 JMenuItem timeConvertMenuItem = new JMenuItem(bundle.getString("convert.time.title"));
267 timeConvertMenuItem.addActionListener(new ChangeMenuToPanelListener(TimeConvertPanel.class, timeConvertMenuItem.getText()));
268 convertMenu.add(timeConvertMenuItem);
269
270 JMenuItem colorConvertMenuItem = new JMenuItem(bundle.getString("convert.color.title"));
271 colorConvertMenuItem.addActionListener(new ChangeMenuToPanelListener(ColorConvertPanel.class, colorConvertMenuItem.getText()));
272 convertMenu.add(colorConvertMenuItem);
273
274 JMenuItem colorPickerMenuItem = new JMenuItem(bundle.getString("picker.color.title"));
275 colorPickerMenuItem.addActionListener(new ChangeMenuToPanelListener(ColorPickerPanel.class, colorPickerMenuItem.getText()));
276 convertMenu.add(colorPickerMenuItem);
277
278 JMenuItem baseConvertMenuItem = new JMenuItem(bundle.getString("convert.base.title"));
279 baseConvertMenuItem.addActionListener(new ChangeMenuToPanelListener(BaseConvertPanel.class, baseConvertMenuItem.getText()));
280 convertMenu.add(baseConvertMenuItem);
281
282 JMenuItem unicodeConvertMenuItem = new JMenuItem(bundle.getString("convert.unicode.title"));
283 unicodeConvertMenuItem.addActionListener(new ChangeMenuToPanelListener(Zh2UnicodeConvertPanel.class, unicodeConvertMenuItem.getText()));
284 convertMenu.add(unicodeConvertMenuItem);
285
286 JMenuItem encodingRecoveryMenuItem = new JMenuItem(bundle.getString("garbled.text.recovery.title"));
287 encodingRecoveryMenuItem.addActionListener(new ChangeMenuToPanelListener(GarbledTextRecoveryPanel.class, encodingRecoveryMenuItem.getText()));
288 convertMenu.add(encodingRecoveryMenuItem);
289
290 JMenuItem relationShipConvertMenuItem = new JMenuItem(bundle.getString("convert.relationship.title"));
291 relationShipConvertMenuItem.addActionListener(new ChangeMenuToPanelListener(RelationShipConvertPanel.class, relationShipConvertMenuItem.getText()));
292 convertMenu.add(relationShipConvertMenuItem);
293
294 JMenuItem unsupervisedProtobufConvertMenuItem = new JMenuItem(bundle.getString("convert.protobuf.unsupervised.title"));
295 unsupervisedProtobufConvertMenuItem.addActionListener(new ChangeMenuToPanelListener(UnsupervisedProtobufConvertPanel.class, unsupervisedProtobufConvertMenuItem.getText()));
296 convertMenu.add(unsupervisedProtobufConvertMenuItem);
297
298 JMenuItem supervisedProtobufConvertMenuItem = new JMenuItem(bundle.getString("convert.protobuf.supervised.title"));
299 supervisedProtobufConvertMenuItem.addActionListener(new ChangeMenuToPanelListener(SupervisedProtobufConvertPanel.class, supervisedProtobufConvertMenuItem.getText()));
300 convertMenu.add(supervisedProtobufConvertMenuItem);
301 }
302
303 private void createAndroidMenu() {
304 JMenu androidMenu = new JMenu(bundle.getString("android.title"));
305 menuBar.add(androidMenu);
306
307 JMenuItem i18nAddMenuItem = new JMenuItem(bundle.getString("android.i18n.add.title"));
308 i18nAddMenuItem.addActionListener(new ChangeMenuToPanelListener(I18nAddPanel.class, i18nAddMenuItem.getText()));
309 androidMenu.add(i18nAddMenuItem);
310
311 JMenuItem i18nFindLongestMenuItem = new JMenuItem(bundle.getString("android.i18n.longest.title"));
312 i18nFindLongestMenuItem.addActionListener(new ChangeMenuToPanelListener(I18nFindLongestPanel.class, i18nFindLongestMenuItem.getText()));
313 androidMenu.add(i18nFindLongestMenuItem);
314
315 JMenuItem i18nRemoveMenuItem = new JMenuItem(bundle.getString("android.i18n.remove.title"));
316 i18nRemoveMenuItem.addActionListener(new ChangeMenuToPanelListener(I18nRemovePanel.class, i18nRemoveMenuItem.getText()));
317 androidMenu.add(i18nRemoveMenuItem);
318
319 JMenuItem screenShotMenuItem = new JMenuItem(bundle.getString("android.screenshot.title"));
320 screenShotMenuItem.addActionListener(new ChangeMenuToPanelListener(ScreenShotPanel.class, screenShotMenuItem.getText()));
321 screenShotMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK));
322 androidMenu.add(screenShotMenuItem);
323
324 JMenuItem monkeyMenuItem = new JMenuItem(bundle.getString("android.monkey.title"));
325 monkeyMenuItem.addActionListener(new ChangeMenuToPanelListener(MonkeyPanel.class, monkeyMenuItem.getText()));
326 androidMenu.add(monkeyMenuItem);
327
328 JMenuItem dumpsysMenuItem = new JMenuItem(bundle.getString("android.dumpsys.title"));
329 dumpsysMenuItem.addActionListener(new ChangeMenuToPanelListener(DumpsysPanel.class, dumpsysMenuItem.getText()));
330 androidMenu.add(dumpsysMenuItem);
331 }
332
333 private void createReverseMenu() {
334 JMenu reverseMenu = new JMenu(bundle.getString("reverse.title"));
335 reverseMenu.setMnemonic(KeyEvent.VK_R);
336 menuBar.add(reverseMenu);
337
338 JMenuItem pluginVersionMenuItem = new JMenuItem(bundle.getString("reverse.plugin.version.title"));
339 pluginVersionMenuItem.addActionListener(new ChangeMenuToUrlListener(Constant.URL_PLUGIN_VERSION));
340 reverseMenu.add(pluginVersionMenuItem);
341
342 JMenuItem apktoolMenuItem = new JMenuItem(bundle.getString("reverse.apktool.title"), KeyEvent.VK_D);
343 apktoolMenuItem.addActionListener(new ChangeMenuToPanelListener(ApktoolPanel.class, apktoolMenuItem.getText()));
344 reverseMenu.add(apktoolMenuItem);
345
346 JMenuItem apkSignMenuItem = new JMenuItem(bundle.getString("reverse.apksigner.title"));
347 apkSignMenuItem.addActionListener(new ChangeMenuToPanelListener(ApkSignerPanel.class, apkSignMenuItem.getText()));
348 reverseMenu.add(apkSignMenuItem);
349
350 JMenuItem jDMenuItem = new JMenuItem(bundle.getString("reverse.jd.gui.title"));
351 jDMenuItem.addActionListener(new ChangeMenToPluginJdListener());
352 reverseMenu.add(jDMenuItem);
353
354 JMenuItem luytenMenuItem = new JMenuItem(bundle.getString("reverse.luyten.title"));
355 luytenMenuItem.addActionListener(new ChangeMenuToPluginLuytenListener());
356 reverseMenu.add(luytenMenuItem);
357
358 JMenuItem jdDuoMenuItem = new JMenuItem(bundle.getString("reverse.jd.duo.title"));
359 jdDuoMenuItem.addActionListener(new ChangeMenuToPluginJdDuoListener());
360 reverseMenu.add(jdDuoMenuItem);
361
362 JMenuItem jdaMenuItem = new JMenuItem(bundle.getString("reverse.jda.title"));
363 jdaMenuItem.addActionListener(new ChangeMenuToPluginJdaListener());
364 reverseMenu.add(jdaMenuItem);
365
366 JMenuItem jADXMenuItem = new JMenuItem(bundle.getString("reverse.jadx.title"));
367 jADXMenuItem.addActionListener(new ChangeMenuToPluginJadxListener());
368 reverseMenu.add(jADXMenuItem);
369
370 JMenuItem aXMLPrinter = new JMenuItem(bundle.getString("reverse.axmlprinter.title"));
371 aXMLPrinter.addActionListener(new ChangeMenuToPanelListener(AxmlPrinterPanel.class, aXMLPrinter.getText()));
372 reverseMenu.add(aXMLPrinter);
373 }
374
375 class ChangeMenuToPanelListener implements ChangeMenuListener {
376
377 Class<? extends EasyPanel> easyPanelClass;
378
379 EasyPanel panel = null;
380
381 String title;
382
383 public ChangeMenuToPanelListener(Class<? extends EasyPanel> easyPanelClass, String title) {
384 this.easyPanelClass = easyPanelClass;
385 this.title = title;
386 panel = createEasyPanel();
387 }
388
389 @Override
390 public boolean isNeedPreChangeMenu() {
391 return panel.isNeedPreChangeMenu();
392 }
393
394 @Override
395 public void onPreChangeMenu(IPreChangeMenuCallBack callBack) {
396 if (panel instanceof PluginPanel pluginPanel) {
397 pluginPanel.preparePlugin(new ChangeMenuPreparePluginController(pluginPanel.getPluginFilename(), pluginPanel.isPluginNeedUnzip(), pluginPanel.isPluginNeedUnzipToSeparateDir(), callBack));
398 }
399 }
400
401 @Override
402 public void onChangeMenu() {
403 UiStateKeeper.save(currentEasyPanel);
404 contentPane.removeAll();
405 contentPane.add(Box.createVerticalGlue());
406 panel.init();
407 panel.setBorder(BorderFactory.createTitledBorder(title));
408 contentPane.add(panel);
409 logger.info("Panel changed: " + panel.getClass().getSimpleName());
410 contentPane.add(Box.createVerticalGlue());
411 contentPane.revalidate();
412 contentPane.repaint();
413 refreshSizeAndLocation();
414 panel.afterPainted();
415 UiStateKeeper.restore(panel);
416 currentEasyPanel = panel;
417 }
418
419 private EasyPanel createEasyPanel() {
420 if (easyPanelClass == null) {
421 return new EasyPanel();
422 }
423 EasyPanel retEasyPanel = null;
424 try {
425 retEasyPanel = easyPanelClass.getDeclaredConstructor().newInstance();
426 } catch (InstantiationException | IllegalAccessException | InvocationTargetException |
427 NoSuchMethodException e) {
428 logger.info("createEasyPanel failed: {}", e.getMessage());
429 }
430 return Objects.requireNonNullElseGet(retEasyPanel, EasyPanel::new);
431 }
432 }
433
434 @Override
435 protected void onWindowClosing(WindowEvent e) {
436 super.onWindowClosing(e);
437 UiStateKeeper.save(currentEasyPanel);
438 }
439
440 @Override
441 protected void onWindowIconified(WindowEvent e) {
442 super.onWindowIconified(e);
443 UiStateKeeper.save(currentEasyPanel);
444 }
445 }